#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXLINE     (1024 * 2)

static
void    Usage(void)
    {
    fprintf(stderr, "Usage:\n");
    fprintf(stderr, "     regress <testfile>\n");
    fprintf(stderr, "Where:\n");
    fprintf(stderr, "    <testfile> contains directive lines.\n");
    exit(EXIT_FAILURE);
    }

static
int     SkipLine(char* Line)
    {
    return *Line == '#' || strspn(Line, " \t\r\n") == strlen(Line);
    }

static
int     GoodLine(char* Line)
    {
    while(*Line)
        {
        if(*Line == '\n')
            {
            *Line++ = '\0';
            return *Line == '\0';
            }
        ++Line;
        }
    return 0;
    }


static
int     DoTest(const char* Command, int Expect, int* Result)
    {
    int     Succeeded = 1;

    printf("regress: '%s'\n", Command);
    *Result     = system(Command);
    if(*Result == -1)
        {
        fprintf(stderr, "system() failed. errno=%d\n", errno);
        perror("");
        exit(1);
        }
    if(*Result != Expect)
        Succeeded   = 0;

    return Succeeded;
    }

int     main(int ArgCount, const char** Args)
    {
    FILE*   Tests;
    int     Expect, Got;
    char*   Result;
    char*   Command;
    int     LineNumber;

    if(ArgCount != 2)
        Usage();

    Tests   = fopen(Args[1], "r");
    if(Tests == NULL)
        {
        fprintf(stderr, "Can't open '%s' for reading.\n", Args[1]);
        Usage();
        }
    Result  = malloc(MAXLINE+1);
    assert(Result != NULL);
    Command = malloc(MAXLINE+1);
    assert(Command != NULL);

    for(LineNumber=1; fgets(Command, MAXLINE, Tests); ++LineNumber)
        {
        if(!GoodLine(Command))
            {
            fprintf(stderr, "'%s' Line %d: not terminated by newline.\n", Args[1], LineNumber);
            exit(EXIT_FAILURE);
            }
        if(SkipLine(Command))
            continue;
        ++LineNumber;
        if(fgets(Result, MAXLINE, Tests) && GoodLine(Result))
            {
            Expect  = atoi(Result);
            if(Expect < 0)
                {
                fprintf(stderr, "File '%s' Line %d: could not make positive integer out of '%s'\n",
                        Args[1], LineNumber, Result);
                exit(EXIT_FAILURE);
                }
            if(!DoTest(Command, Expect, &Got))
                {
                fprintf(stderr, "File '%s' Line %d: test failed:\n  '%s'\n   "
                        "Expecting status %d, got %d\n",
                        Args[1], LineNumber, Command, Expect, Got);
                exit(EXIT_FAILURE);
                }
            }
        else
            {
            fprintf(stderr, "'%s' Line %d: not terminated by newline.\n", Args[1], LineNumber);
            exit(EXIT_FAILURE);
            }
        }

    printf("all regression tests completed successfully!\n");

    return EXIT_SUCCESS;
    }
